package com.tsy.graduate.utils;

import com.google.common.base.Strings;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;

public class DateUtils {

    /**
     * 根据时间戳获取月份 例如 12月
     *
     * @param timestamp
     * @return
     */
    public static String getMonthByTimestamp(int timestamp) {
        if (timestamp <= 0) {
            return "";
        }

        String format = "MM";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(timestamp + "000"))) + "月";
    }

    /**
     * 获取精确到毫秒的时间戳
     *
     * @return
     */
    public static long getAccurateNowTimestamp() {
        Instant instant = Instant.now();
        return instant.toEpochMilli();
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @return
     */
    public static int getCurrentTimestamp() {
        Date date = new Date();
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        }
        return 0;
    }

    /**
     * @return int
     * @Description <获取Date的时间戳>
     * @Translation <Get the timestamp of the Date>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 12:55
     * @Param [date]
     * @since 1.0.0
     **/
    public static int getDateTimestamp(Date date) {
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        }
        return 0;
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到秒的字符串
     * @param format
     * @return
     */
    public static String timeStamp2Date(int seconds, String format) {
        if (Utils.isEmpty(seconds)) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds + "000")));
    }

    /**
     * 日期格式字符串转换成时间戳
     *
     * @param date_str 字符串日期
     * @param format   如：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static int date2TimeStamp(String date_str, String format) {
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String timestamp = String.valueOf(sdf.parse(date_str).getTime() / 1000);
            int length = timestamp.length();
            if (length > 3) {
                return Integer.valueOf(timestamp.substring(0, length));
            }
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 拿到一个日期提前天数的date,并且是精确到天
     *
     * @param
     * @return
     */
    public static Date getDateForDay(Date date, int days) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化对象
        Calendar calendar = Calendar.getInstance();//日历对象
        calendar.setTime(date);//设置当前日期
        calendar.add(Calendar.DATE, -(days)); //
        Date time = calendar.getTime();
        return time;
    }

    /**
     * 获取当前的日期
     *
     * @return
     */
    public static String getTodayDateStr() {
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(d);
    }

    public static String getTodayDateStr(String format) {
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    /**
     * 判断时间戳是不是今天
     *
     * @param timestamp
     * @return
     */
    public static boolean isTimestampToday(int timestamp) {
        boolean isToday = false;
        Date date;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            date = sdf.parse(sdf.format(new Date()));

            Long todayBegin = date.getTime() / 1000;
            Long todayEnd = todayBegin + 86400;
            if (timestamp > todayBegin && timestamp < todayEnd) {
                isToday = true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return isToday;
    }


    public static Integer long2Int(long date) {

        Date date1 = new Date(date);
//        Long time = date.getTime();
        String timestamp = String.valueOf(date1.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        }
        return 0;
    }

    public static Integer day2Second(int days) {
        return days * 24 * 3600;
    }

    /**
     * 对比两个时间差是否超过24小时 超过返回true
     *
     * @param xTimestmp 被对比时间
     * @param Ytimestmp 对比时间
     * @return
     */
    public static boolean isTimeOver24Hours(int xTimestmp, int Ytimestmp) {
        int secondsOfOneDay = day2Second(1);
        if (Ytimestmp + secondsOfOneDay <= xTimestmp) {
            return true;
        }
        return false;
    }

    /**
     * 日期格式字符串转换成Date
     *
     * @param date_str 字符串日期
     * @param format   如：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Date dateStr2Date(String date_str, String format) {
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd";
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date = sdf.parse(date_str);

            return date;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期Date转换成String
     *
     * @param date   字符串日期
     * @param format 如：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String date2String(Date date, String format) {
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd";
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String dateStr = sdf.format(date);

            return dateStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return int
     * @Description <获取距离一天结束还有多少时间ttl>
     * @Translation <Get the distance from the end of the day, how much time ttl>
     * @Author WenHe/MrYida
     * @Date 2018/12/6 15:06
     * @Param []
     * @since 1.0.0
     **/
    public static int getDayTtl() {
        int endTime = DateUtils.date2TimeStamp(DateUtils.getTodayDateStr() + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
        int startTime = getCurrentTimestamp();
        return endTime - startTime;
    }


    /**
     * @return int[]
     * @Description <获取今日的时间戳区间startTime - endTime>
     * @Translation <Get today's timestamp interval startTime - endTime>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 10:52
     * @Param [startTime:时间戳区间起始时间, endTime:时间戳区间结束时间]
     * @since 1.0.0
     **/
    public static int[] getTodayTimestampInterval(String startTime, String endTime) {
        int[] timestampInterval = new int[2];
        String today = getTodayDateStr();
        timestampInterval[0] = date2TimeStamp(today + " " + startTime, "yyyy-MM-dd HH:mm:ss");
        timestampInterval[1] = date2TimeStamp(today + " " + endTime, "yyyy-MM-dd HH:mm:ss");
        return timestampInterval;
    }


    /**
     * @return int[]
     * @Description <获取指定日期的时间戳区间startTime - endTime>
     * @Translation <Get the timestamp interval of the specified date startTime - endTime>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 10:54
     * @Param [date:指定日期, startTime:开始时间, endTime:结束时间]
     * @since 1.0.0
     **/
    public static int[] getDateTimestampInterval(String date, String startTime, String endTime) {
        int[] timestampInterval = new int[2];
        timestampInterval[0] = date2TimeStamp(date + " " + startTime, "yyyy-MM-dd HH:mm:ss");
        timestampInterval[1] = date2TimeStamp(date + " " + endTime, "yyyy-MM-dd HH:mm:ss");
        return timestampInterval;
    }

    /**
     * @return int[]
     * @Description <获取N天前的时间戳区间 startTime - endTime>
     * @Translation <Get the timestamp interval before N days startTime - endTime>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 10:55
     * @Param [days:N天前, startTime:时间戳区间起始时间, endTime:时间戳区间结束时间]
     * @since 1.0.0
     **/
    public static int[] getDateTimestampIntervalBeforeDays(int days, String startTime, String endTime) {
        int[] timestampInterval = new int[2];
        Date date = getDateForDay(new Date(), days);
        String dateString = date2String(date, "yyyy-MM-dd");
        timestampInterval[0] = date2TimeStamp(dateString + " " + startTime, "yyyy-MM-dd HH:mm:ss");
        timestampInterval[1] = date2TimeStamp(dateString + " " + endTime, "yyyy-MM-dd HH:mm:ss");
        return timestampInterval;
    }

    /**
     * @return int[]
     * @Description <获取两个时间的时间戳区间>
     * @Translation <Get the timestamp interval between two times>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 11:41
     * @Param [startTime:时间戳区间开始时间, endTime:时间戳区间结束时间, format:时间格式]
     * @since 1.0.0
     **/
    public static int[] getTimestampIntervalBetweenTwoDateString(String startTime, String endTime, String format) {
        int[] timeStampInterval = new int[2];
        timeStampInterval[0] = date2TimeStamp(startTime, format);
        timeStampInterval[1] = date2TimeStamp(endTime, format);
        return timeStampInterval;
    }

    /**
     * @return int[]
     * @Description <获取当前时间与N天前此时间的时间戳区间>
     * @Translation <Get the current time and the timestamp interval of this time before N days>
     * @Author WenHe/MrYida
     * @Date 2018/11/27 12:57
     * @Param [days:N天]
     * @since 1.0.0
     **/
    public static int[] getTimestampIntervalBetweenNowAndDaysBefor(int days) {
        int[] timeStampInterval = new int[2];
        Date now = new Date();
        Date before = getDateForDay(now, days);
        timeStampInterval[0] = getDateTimestamp(before);
        timeStampInterval[1] = getDateTimestamp(now);
        return timeStampInterval;
    }

    /**
     * @return java.lang.String
     * @Description <通过字符串时间获取星期几>
     * @Translation <Get the day of the week by string time>
     * @Author WenHe/MrYida
     * @Date 2018/12/3 19:35
     * @Param [date:字符串类型时间, format:时间格式]
     * @since 1.0.0
     **/
    public static String getWeekByStringDate(String date, String format) {
        if (Strings.isNullOrEmpty(format)) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        Date date1;
        try {
            date1 = simpleDateFormat.parse(date);
            cal.setTime(date1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int top = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return weekDays[top];
    }

    /**
     * @return java.lang.String
     * @Description <通过时间戳获取星期几>
     * @Translation <Get the day of the week by timestamp>
     * @Author WenHe/MrYida
     * @Date 2018/12/3 19:38
     * @Param [timestamp:时间戳]
     * @since 1.0.0
     **/
    public static String getWeekByTimestamp(int timestamp) {
        if (timestamp <= 0) {
            return null;
        }
        String time = timeStamp2Date(timestamp, "yyyy-MM-dd HH:mm:ss");
        return getWeekByStringDate(time, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * @return java.lang.String
     * @Description <计算得到该时间相差的年月日时分秒的时间>
     * @Translation <Calculate the time, minute, minute, and second of the time difference>
     * @Author WenHe/MrYida
     * @Date 2018/12/4 15:01
     * @Param [time, format, year, month, day, hour, minute, second]
     * @since 1.0.0
     **/
    public static String getCountTimeByTime(String time, String format, int year, int month, int day, int hour, int minute, int second) {
        String resultTime;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = new Date();
        try {
            date = sdf.parse(time);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        calendar.add(Calendar.HOUR, hour);
        calendar.add(Calendar.MINUTE, minute);
        calendar.add(Calendar.SECOND, second);
        resultTime = sdf.format(calendar.getTime());
        return resultTime;
    }

    /**
     * @return int[]
     * @Description <获取指定日期的整点时间戳>
     * @Translation <Get the hourstamp of the specified date>
     * @Author WenHe/MrYida
     * @Date 2018/12/12 10:21
     * @Param [date:指定日期]
     * @since 1.0.0
     **/
    public static int[] getDateAllWholeTimeByHour(String date) {
        String format = "yyyy-MM-dd HH:mm:ss";
        int[] result = new int[25];
        result[0] = date2TimeStamp(date + "00:00:00", format);
        result[1] = date2TimeStamp(date + "01:00:00", format);
        result[2] = date2TimeStamp(date + "02:00:00", format);
        result[3] = date2TimeStamp(date + "03:00:00", format);
        result[4] = date2TimeStamp(date + "04:00:00", format);
        result[5] = date2TimeStamp(date + "05:00:00", format);
        result[6] = date2TimeStamp(date + "06:00:00", format);
        result[7] = date2TimeStamp(date + "07:00:00", format);
        result[8] = date2TimeStamp(date + "08:00:00", format);
        result[9] = date2TimeStamp(date + "09:00:00", format);
        result[10] = date2TimeStamp(date + "10:00:00", format);
        result[11] = date2TimeStamp(date + "11:00:00", format);
        result[12] = date2TimeStamp(date + "12:00:00", format);
        result[13] = date2TimeStamp(date + "13:00:00", format);
        result[14] = date2TimeStamp(date + "14:00:00", format);
        result[15] = date2TimeStamp(date + "15:00:00", format);
        result[16] = date2TimeStamp(date + "16:00:00", format);
        result[17] = date2TimeStamp(date + "17:00:00", format);
        result[18] = date2TimeStamp(date + "18:00:00", format);
        result[19] = date2TimeStamp(date + "19:00:00", format);
        result[20] = date2TimeStamp(date + "20:00:00", format);
        result[21] = date2TimeStamp(date + "21:00:00", format);
        result[22] = date2TimeStamp(date + "22:00:00", format);
        result[23] = date2TimeStamp(date + "23:00:00", format);
        result[24] = date2TimeStamp(date + "23:59:59", format);
        return result;
    }

    /**
     * @return java.util.LinkedHashMap{java.lang.String,java.lang.Integer}
     * @Description <获取指定日期整点时间戳的map>
     * @Translation <Get the map of the timestamp of the specified date>
     * @Author WenHe/MrYida
     * @Date 2018/12/12 10:22
     * @Param [date:指定日期]
     * @since 1.0.0
     **/
    public static LinkedHashMap<String, Integer> getDateAllWholeTimeByHourMap(String date) {
        int[] time = getDateAllWholeTimeByHour(date);
        LinkedHashMap<String, Integer> wholeTimeMap = new LinkedHashMap<>();
        String today = getTodayDateStr("yyyy-MM-dd ");
        wholeTimeMap.put(today + "00:00:00", time[0]);
        wholeTimeMap.put(today + "01:00:00", time[1]);
        wholeTimeMap.put(today + "02:00:00", time[2]);
        wholeTimeMap.put(today + "03:00:00", time[3]);
        wholeTimeMap.put(today + "04:00:00", time[4]);
        wholeTimeMap.put(today + "05:00:00", time[5]);
        wholeTimeMap.put(today + "06:00:00", time[6]);
        wholeTimeMap.put(today + "07:00:00", time[7]);
        wholeTimeMap.put(today + "08:00:00", time[8]);
        wholeTimeMap.put(today + "09:00:00", time[9]);
        wholeTimeMap.put(today + "10:00:00", time[10]);
        wholeTimeMap.put(today + "11:00:00", time[11]);
        wholeTimeMap.put(today + "12:00:00", time[12]);
        wholeTimeMap.put(today + "13:00:00", time[13]);
        wholeTimeMap.put(today + "14:00:00", time[14]);
        wholeTimeMap.put(today + "15:00:00", time[15]);
        wholeTimeMap.put(today + "16:00:00", time[16]);
        wholeTimeMap.put(today + "17:00:00", time[17]);
        wholeTimeMap.put(today + "18:00:00", time[18]);
        wholeTimeMap.put(today + "19:00:00", time[19]);
        wholeTimeMap.put(today + "20:00:00", time[20]);
        wholeTimeMap.put(today + "21:00:00", time[21]);
        wholeTimeMap.put(today + "22:00:00", time[22]);
        wholeTimeMap.put(today + "23:00:00", time[23]);
        wholeTimeMap.put(today + "23:59:59", time[24]);
        return wholeTimeMap;
    }

    /**
     * 获取传入的时间所在的半小时区间 比如传入的时间是 11：22：00.000 那么返回 11：00：00.000，11：29：59.999
     *
     * @param date
     * @return
     */
    public static long[] halfOur(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < 30) {
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            long start = calendar.getTimeInMillis();
            calendar.set(Calendar.MILLISECOND, 999);
            calendar.set(Calendar.MINUTE, 29);
            calendar.set(Calendar.SECOND, 59);
            long end = calendar.getTimeInMillis();
            return new long[]{start, end};
        } else {
            calendar.set(Calendar.MINUTE, 30);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            long start = calendar.getTimeInMillis();

            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 999);
            long end = calendar.getTimeInMillis();
            return new long[]{start, end};
        }
    }

    /**
     * @param date 当天的某一个时刻
     * @return 当天00:00:00.000 和当天 23：59:59.000的时间
     */
    public static long[] currentDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long start = calendar.getTimeInMillis();
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        long end = calendar.getTimeInMillis();
        return new long[]{start, end};
    }

    public static int[] currentDateTimestamp(Date date) {
        long[] longTime = currentDate(date);
        long start = longTime[0];
        int startTimestamp = long2Int(start);
        long end = longTime[1];
        int endTimestamp = long2Int(end);
        return new int[]{startTimestamp, endTimestamp};
    }
}
